package com.googlecode.archimedes.filegen.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.lang.builder.HashCodeBuilder;

import com.googlecode.archimedes.filegen.model.validator.Validator;

/**
 * A Member represents attributes of Entities
 * 
 * @author John Lema
 * @version $Id: Member.java 1830 2005-12-05 22:14:04 +0000 (Mon, 05 Dec 2005) erik $
 *
 * Created on Sep 18, 2003
 */
public abstract class Member extends AbstractAsset implements Inheritable, Comparable<Member> {

    private String         memberName  = "UNDEFINED";
    private String         returnType  = "UNDEFINED";
    private String         visibility  = "UNDEFINED";
    private String         displayName = "UNDEFINED";
    private String         description = "No Description.";
    private boolean        required    = false;
    private boolean        readOnly    = false;
    private boolean        hidden      = false;
    private boolean        detailOnly  = false;
    private boolean        summaryOnly = false;
    private Integer        order       = 0;

    public List<Validator> validators  = new ArrayList<Validator>();

    /**
     * The members Java name
     * 
     * @return MemberName a String of the memberName
     */
    public String getMemberName() {
        return memberName;
    }

    /**
     * Returns the Display Name
     * @return a String of the Display Name
     */
    public String getDisplayName() {
        return displayName;
    }

    /**
     * The members Display Name
     * @param displayName like "First Name"
     */
    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }

    /**
     * Can only be "public", "private" or "protected"
     * if anything else is entered, it defaults to "public"
     * 
     * @return the String visibility of this member
     */
    public String getVisibility() {
        return visibility;
    }

    /**
     * Can only be "public", "private" or "protected"
     * if anything else is entered, it defaults to "public"
     * 
     * @param visibility
     */
    public void setVisibility(String visibility) {
        if (visibility.equalsIgnoreCase("public") || visibility.equalsIgnoreCase("private") || visibility.equalsIgnoreCase("protected")) {
            this.visibility = visibility;
        } else {
            this.visibility = "public";
        }
    }

    /**
     * like "firstname"
     * 
     * @param memberName
     */
    public void setMemberName(String memberName) {
        this.memberName = memberName;
    }

    /**
     * to be used IFF using FreeMarker tempaltes and Bean notation
     * 
     * @param Required - Boolean
     */
    public boolean isRequired() {
        return required;
    }

    /**
     * Set if the member is required for complete
     * 
     * @param isRequired - Boolean
     */
    public void setRequired(boolean isRequired) {
        this.required = isRequired;
    }

    /**
     * Gets the return type of the member
     * 
     * @return a String representing the return type
     */
    public String getReturnType() {
        return returnType;
    }

    /**
     * Sets the Return type of the member
     * 
     * @param returnType like String, or Collection
     */
    public void setReturnType(String returnType) {
        this.returnType = returnType;
    }

    /**
     * Returns the readOnly.
     *
     * @return boolean value of readOnly
     */
    public boolean getReadOnly() {
        return readOnly;
    }

    /**
     * Sets the readOnly
     * 
     * @param readOnly The readOnly to set.
     */
    public void setReadOnly(boolean readOnly) {
        this.readOnly = readOnly;
    }

    /**
     * Returns an empty list as Members do not have any subordinate assets.
     * 
     * @see com.tps.filegen.model.Asset#getSubordinateAssets()
     */
    public Collection<? extends Asset> getSubordinateAssets() {
        return new ArrayList<Asset>();
    }

    /**
     * Returns if this member should be "hidden"
     *
     * @return boolean value of hidden
     */
    public boolean getHidden() {
        return hidden;
    }

    /**
     * Sets if this member is hidden on not
     * 
     * @param hidden The boolean to set.
     */
    public void setHidden(boolean hidden) {
        this.hidden = hidden;
    }

    /**
     * @return
     */
    public List<Validator> getValidators() {
        if (this.validators == null) { return new ArrayList<Validator>(); }
        return validators;
    }

    /**
     * @param members
     */
    public void setValidators(List<Validator> validators) {
        this.validators = validators;
    }

    public void addValidator(Validator validator) {
        validators.add(validator);
    }

    /**
     * Returns the detailOnly.
     *
     * @return boolean value of detailOnly
     */
    public boolean getDetailOnly() {
        return detailOnly;
    }

    /**
     * Sets the detailOnly
     * @param detailOnly The detailOnly to set.
     */
    public void setDetailOnly(boolean detailOnly) {
        this.detailOnly = detailOnly;
    }

    /** 
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        return new HashCodeBuilder(13, 29).append(memberName).toHashCode();
    }

    /** 
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {

        if (obj != null && obj instanceof Member) {
            Member other = (Member) obj;
            return this.memberName.equals(other.memberName);
        }

        return false;
    }

    /**
     * Returns the description.
     *
     * @return String value of description
     */
    public String getDescription() {
        return description;
    }

    /**
     * Sets the description
     * @param description The description to set.
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * Returns the order.
     *
     * @return Integer value of order
     */
    public Integer getOrder() {
        return order;
    }

    /**
     * Sets the order
     * @param order The order to set.
     */
    public void setOrder(Integer order) {
        this.order = order;
    }

    /** 
     * @see java.lang.Comparable#compareTo(T)
     */
    public int compareTo(Member obj) {
        Member lhs = this;
        Member rhs = obj;
        return lhs.getOrder().compareTo(rhs.getOrder());
    }

    /**
     * Returns the summaryOnly.
     *
     * @return boolean value of summaryOnly
     */
    public boolean getSummaryOnly() {
        return summaryOnly;
    }

    /**
     * Sets the summaryOnly
     * @param summaryOnly The summaryOnly to set.
     */
    public void setSummaryOnly(boolean summaryOnly) {
        this.summaryOnly = summaryOnly;
    }
}
